# -*- coding: utf-8 -*-

from dtcloud.fields import Command
from .BaseConvert import Convert

base_offset_fields = ['create_uid', 'write_uid', '__last_update', 'display_name']


class One2ManyConvert(Convert):
    field_type = 'one2many'

    @classmethod
    def to_read(cls, rec, field, **kwargs):
        record = rec[field.name]
        if not record:
            return []

        # 如果存在 _rec_name 则只读取 id 和 _rec_name字段
        # 如果不存在 _rec_name 则读取所有字段，但是不读取 base_offset_fields 中的字段
        fields = ('id', record._rec_name) if record._rec_name else [f for f in record._fields if
                                                                    f not in base_offset_fields]
        return record.read(fields)

    @classmethod
    def to_field(cls, value, metadata=None, update=False):

        def __handle_update(value):
            """
                当前orm只支持type为josnify的请求方式的
                1、更新的时候传过来的是IDS集合: 比如 [1,2,3,4] 这时候更新时需要使用Command.set([1,2,3,4])
                2、更新的时候传过来的是字典集合:
                    'child_ids': [{'a':1,b:2},{'a':3,b:4}] 数据中并不包含id字段，说明是新增数据，需要使用Command.create()
                    'child_ids': [{'id':1,'a':1,b:2},{'id':2,'a':3,b:4}] 数据中包含需要更新的id字段，说明是更新数据，需要使用Command.update()
            """
            if isinstance(value, list):
                if all(isinstance(i, int) for i in value):
                    return Command.set(value)
                elif all(isinstance(i, dict) for i in value):
                    return [Command.update(id=i.pop('id'), **i) if 'id' in i else Command.create(i) for i in value]
                else:
                    raise ValueError('传递的值不是包含正整数的数据或字典')
            elif isinstance(value, dict):
                if 'id' in value:
                    return Command.update(id=value.pop('id'), **value)
                else:
                    return Command.create(value)
            else:
                raise ValueError('未知的值类型')

        def __handle_struct_value(struct_value, metadata):
            if isinstance(struct_value, (tuple, list)):
                if all(isinstance(i, int) for i in struct_value):
                    return [Command.link(int(d)) for d in struct_value]
                elif all(isinstance(i, dict) for i in struct_value):
                    return [Command.create({**i, **{metadata.get('relation_field', 'default_value'): False}}) for i in
                            struct_value]
                else:
                    raise ValueError('传递的值不是数字或字典')
            else:
                raise ValueError('传递的值不是元组或列表')

        if update:
            return __handle_update(value)

        if isinstance(value, (str, list, int)):
            try:
                struct_value = eval(value) if isinstance(value, str) else value
                return __handle_struct_value(struct_value, metadata)
            except Exception as e:
                raise ValueError(f'解析值时出错: {e.args}')

        elif isinstance(value, dict):
            metadata = metadata or {}
            return [Command.create({**value, **{metadata.get('relation_field', 'default_value'): False}})]

        else:
            raise ValueError('未知的值类型')

        # if update:  # 如果是更新操作
        #     if isinstance(value, list):
        #         if all(map(lambda i: isinstance(i, int), value)):
        #             return Command.set(value)
        #         elif all(map(lambda i: isinstance(i, dict), value)):
        #             return [
        #                 Command.update(id=i.pop('id'), **i) if 'id' in i else Command.create(i)
        #                 for i in value
        #             ]
        #         else:
        #             raise ValueError('传递的值不是包含正整数的数据或字典')
        #     elif isinstance(value, dict):
        #         if 'id' in value:
        #             return Command.update(id=value.pop('id'), **value)
        #         else:
        #             return Command.create(value)
        # if isinstance(value, (str, list, int)):
        #     try:
        #         struct_value = eval(value) if isinstance(value, str) else value
        #         if isinstance(struct_value, (tuple, list)):
        #             if all(map(lambda i: isinstance(i, int), struct_value)):
        #                 return list(map(lambda d: Command.link(int(d)), struct_value))
        #             elif all(map(lambda i: isinstance(i, dict), struct_value)):
        #                 return [Command.create({**i, **{metadata.get('relation_field', 'default_value'): False}}) for i
        #                         in struct_value]
        #             else:
        #                 raise ValueError('传递的值不是数字或字典')
        #     except Exception as e:
        #         raise ValueError(f'{e.args}')
        # elif isinstance(value, dict):
        #     metadata = metadata or {}
        #     return [Command.create({**value, **{metadata.get('relation_field', 'default_value'): False}})]
        # else:
        #     raise ValueError('未知的值类型')

    @classmethod
    def to_domain(cls, field, value, **kwargs):
        if isinstance(value, str):  # 1,2,3 适配多个id拼接的字符串
            data_rec = value.split(',') if ',' in value else [value]
        elif isinstance(value, int):  # 1 适配单个id
            data_rec = [value]
        else:
            data_rec = value

        try:
            if isinstance(data_rec, tuple) or isinstance(data_rec, list):
                return [(field.name, 'in', [int(d) for d in data_rec])]
        except Exception as e:
            raise ValueError(f'{e.args}')
